#include "core_headers.hpp"
#include "EventLoop.hpp"
#include "Acceptor.hpp"
#include "LoopThreadPool.hpp"
#include "Connection.hpp"

using Functor = std::function<void()>;
using ConnectCallback = std::function<void(const Ptrconnection &)>;
using MessageCallback = std::function<void(const Ptrconnection &, Buffer *)>;
using CloseCallback = std::function<void(const Ptrconnection &)>;
using AnyEventCallback = std::function<void(const Ptrconnection &)>;
class TcpServer
{
private:
	// 添加定时销毁任务
	void RunAfterInLoop(int delay, const Functor &task)
	{
		_next_id++;
		_baseloop.TaskAdd(_next_id, delay, task);
	}
	// 为新连接构造一个Connection进行管理
	void NewConnection(int fd)
	{
		_next_id++;
		Ptrconnection ch(new Connection(_next_id, fd, _pool.NextLoop()));
		ch->SetMessageCallback(_message_callback);
		ch->SetCloseCallback(_close_callback);
		ch->SetConnectCallback(_connect_callback);
		ch->SetAnyEventCallback(_event_callback);
		ch->SetServeCloseCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
		if (_enable_inactive_release)
			ch->EnableInactiveRelease(_timeout);
		ch->Establish();
		_conns.insert(std::make_pair(_next_id, ch));
	}
	void RemoveConnectionInLoop(const Ptrconnection &conn)
	{
		int id = conn->Id();
		auto it = _conns.find(id);
		if (it != _conns.end())
		{
			_conns.erase(id);
		}
	}
	// 从_conns中移除对应的Connection链接
	void RemoveConnection(const Ptrconnection &conn)
	{
		_baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
	}

public:
	TcpServer(int port)
		: _next_id(0), _accept(&_baseloop, port), _pool(&_baseloop)
	{
		_accept.SetAcceptorCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
	}
	void SetConnectCallback(const ConnectCallback &cd)
	{
		_connect_callback = cd;
	}
	void SetMessageCallback(const MessageCallback &cd)
	{
		_message_callback = cd;
	}
	void SetCloseCallback(const CloseCallback &cd)
	{
		_close_callback = cd;
	}
	void SetAnyEventCallback(const AnyEventCallback &cd)
	{
		_event_callback = cd;
	}
	// 启动非活跃链接销毁
	void EnableInactiveRelease(int timeout)
	{
		_timeout = timeout;
		_enable_inactive_release = true;
	}
	// 设置线程数量
	void SetThreadCount(int count)
	{
		_pool.SetThreadCount(count);
	}
	// 添加定时任务
	void RunAfter(int delay, const Functor &task)
	{
		_baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, delay, task));
	}
	// 启动
	void Start()
	{
		_pool.Create();
		_accept.Listen();
		_baseloop.Start();
	}

private:
	uint64_t _next_id;
	int _timeout;										// 超时时间
	bool _enable_inactive_release;						// 是否启动非活跃链接销毁
	EventLoop _baseloop;								// 这是主线程的EventLoop对象，负责监听事件的处理
	Acceptor _accept;									// 这是监听套接字的管理对象
	LoopThreadPool _pool;								// 这是从属EventLoop线程池
	std::unordered_map<uint64_t, Ptrconnection> _conns; // 保存管理所有连接对应的shared_ptr对象

	ConnectCallback _connect_callback;
	MessageCallback _message_callback;
	CloseCallback _close_callback;
	AnyEventCallback _event_callback;
};

// 忽略 SIGPIPE 是网络编程常见手段，防止因对端断开连接后继续写操作导致程序异常终止。
class NetWork
{
public:
	NetWork()
	{
		DEL_LOG("SIGPIPE init");
		signal(SIGPIPE, SIG_IGN);
	}
};

static NetWork net;